package cn.wolfcode.wolf2w.service.impl;


import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.Travel;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.exception.LogicException;
import cn.wolfcode.wolf2w.query.StrategyQuery;
import cn.wolfcode.wolf2w.query.TravelQuery;
import cn.wolfcode.wolf2w.redis.service.IUserInfoRedisService;
import cn.wolfcode.wolf2w.repository.TravelRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.ITravelService;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.vo.TravelCondition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class TravelServiceImpl implements ITravelService {
    @Autowired
    private TravelRepository travelRepository;
    @Autowired
    private MongoTemplate template;
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private IUserInfoRedisService userInfoRedisService;
    @Autowired
    private IUserInfoService userInfoService;


    @Override
    public void insert(Travel travel) {
        travel.setId(null);
        travelRepository.save(travel);
    }

    @Override
    public void delete(String id) {
        travelRepository.deleteById(id);
    }

    @Override
    public void update(Travel travel) {
        travelRepository.save(travel);
    }

    @Override
    public Travel findById(String id) {
        Optional<Travel> travel = travelRepository.findById(id);

        Travel travel1 = travel.orElse(null);
        travel1.setAuthor(userInfoService.selectOne(travel1.getUserId()));
        return travel1;
    }

    @Override
    public List<Travel> findAll() {
        List<Travel> all = travelRepository.findAll();
        return all;
    }

    @Override
    public Page<Travel> query(TravelQuery qo) {
        Query query = new Query();

        if (qo.getDayType() != -1){
            query.addCriteria(Criteria.where("day").gte(TravelCondition.DAYTYPE_MAP.get(qo.getDayType()).getMin()).lte(TravelCondition.DAYTYPE_MAP.get(qo.getDayType()).getMax()));
        }

        if (qo.getPerExpendType() != -1){
            query.addCriteria(Criteria.where("perExpend").gte(TravelCondition.PEREXPENDTYPE_MAP.get(qo.getPerExpendType()).getMin()).lte(TravelCondition.PEREXPENDTYPE_MAP.get(qo.getPerExpendType()).getMax()));
        }

        if (StringUtils.hasLength(qo.getDestId())){
            query.addCriteria(Criteria.where("destId").regex(qo.getDestId()));
        }

        //游记发布了, 并且是公开的才显示
        if (qo.getDifference() == 1){
            Criteria criteria = new Criteria();
            query.addCriteria(criteria.andOperator(Criteria.where("state").is(2),Criteria.where("isPublic").is(1)));
        }


        if (qo.getState() == 1){
            query.addCriteria(Criteria.where("state").is(1));
        }else if (qo.getState() == -1){
            query.addCriteria(Criteria.where("state").is(3));
        }else if (qo.getState() == 2){
            query.addCriteria(Criteria.where("state").is(2));
        }else if (qo.getState() == 4){
            query.addCriteria(Criteria.where("state").is(4));
        }

        if (StringUtils.hasText(qo.getKeyword())) {
            query.addCriteria(Criteria.where("name").regex(qo.getKeyword()));
        }
        long total = template.count(query, Travel.class);
        System.out.println(total);
        if (total == 0) {
            return Page.empty();
        }

        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
        if (qo.getOrderType() == 1){
            pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC, "createTime");
        }else if (qo.getOrderType() == 2){
            pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC, "viewnum");
        }

        query.with(pageable);
        List<Travel> list = template.find(query, Travel.class);
        return new PageImpl<>(list, pageable, total);
    }

    @Override
    public void changeState(String id, int state) {
        //先判断有没有这个游记,而且状态是不是需要审核
        Travel travel = this.findById(id);
        if (travel == null) {
            throw new LogicException("游记参数错误了");
        }

        //审核通过,修改状态,修改创建时间,修改更新时间
        if (state == 2){
            travel.setState(state);
            travel.setCreateTime(new Date());
            travel.setLastUpdateTime(new Date());
        }


        //审核不通过
        if (state == 3){
            travel.setState(state);
            travel.setCreateTime(null);
            travel.setLastUpdateTime(new Date());
        }

        //下架该篇游记
        if (state == 1 && travel.getState() == 2){
            travel.setState(4);
            travel.setLastUpdateTime(new Date());
        }
        this.update(travel);
    }


    @Override
    public List<Travel> findByDestIdTon3(String destId) {
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC, "viewnum");
        List<Travel> travels = travelRepository.findByDestId(destId,pageable);
        for (Travel travel : travels) {
            travel.setAuthor(userInfoService.selectOne(travel.getUserId()));
        }
        return travels;
    }

    @Override
    public Travel saveOrUpdate(Travel travel) {

        travel.setDestName(destinationService.selectOne(travel.getDestId()).getName());
        travel.setLastUpdateTime(new Date());

        if (StringUtils.hasLength(travel.getId())){
            Travel travel1 = this.findById(travel.getId());
            travel.setViewnum(travel1.getViewnum());
            travel.setReplynum(travel1.getReplynum());
            travel.setFavornum(travel1.getFavornum());
            travel.setSharenum(travel1.getSharenum());
            travel.setThumbsupnum(travel1.getThumbsupnum());
            travel.setCreateTime(travel1.getCreateTime());
            this.update(travel);
            return travel;
        }else{
            travel.setCreateTime(new Date());
            travel.setId(null);
            Travel save = travelRepository.save(travel);
            return save;
        }

    }

    @Override
    public List<Travel> findByDestId(String id) {
        List<Travel> travels = travelRepository.findByDestId(id, null);
        for (Travel travel : travels) {
            travel.setAuthor(userInfoService.selectOne(travel.getUserId()));
        }
        return travels;
    }

   /* @Override
    public boolean UserEstimateAuthor(String id, UserInfo userInfo) {
        Travel travel = this.findById(id);
        if (userInfo == null || travel == null){
            return false;
        }
        if (userInfo.getId().equals(travel.getUserId())){
            return true;
        }
        return false;
    }*/

}
